package com.wolfsea.defineviewgrouppaper
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.get
import kotlinx.coroutines.*

/**
 *@desc  PaperContainer
 *@author liuliheng
 *@time 2022/11/16  22:19
 **/
class PaperContainer @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null
) : ConstraintLayout(context, attributeSet), CoroutineScope by MainScope() {

    /* 待处理问题:
    *  1.增加题目类型
    *
    *    a.待图片展示的选择题---已完成
    *    b.答案显示在一行---不可行
    *
    *  2.增加开始做题按钮  结束答题按钮---已完成
    *
    *    a.开始做题 不点击不能做题  不能获取答案
    *    b.结束答题  不能做题  可以获取答案
    *
    *  3.多数据时  先显示一部分  滑动后逐步显示---已完成
    *
    *  4.ScrollView嵌套自定义ViewGroup不能滑动
    *
    * */
    private var downX = 0
    private var downY = 0
    private var itemDownY = 0

    private var movedY = 0
    private var itemMovedX = 0
    private var indexOfItemMovedX = 0

    private var startIndex = 0
    private var endIndex = 0
    private var titleAnswersIndex = -1

    private var showChildCount = 4
    private var totalChildCount = 0

    private var movedTotalHeight = 0

    //屏幕高度
    private val mScreenHeight = context.resources.displayMetrics.heightPixels
    //已使用高度
    private var usedViewHeight = 0

    private var canEdited = false

    private lateinit var dataSet: MutableList<PaperContent>

    //题目编号与所选答案item映射关系
    private val itemMap = mutableMapOf<Int, IntArray>()

    //题目编号与所选答案item数量映射关系
    private val imageViewMap = mutableMapOf<Int, Array<AppCompatImageView?>>()

    //记录是否是标题
    private val titlesCountMap = mutableMapOf<Int, Boolean>()

    //题目编号与标题|答案item总高度映射关系
    private val itemHeightMap = mutableMapOf<Int, Int>()

    private val titleViews = mutableMapOf<Int, View>()

    private val answerViews = mutableMapOf<String, View>()

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(
            MeasureSpec.getSize(widthMeasureSpec),
            MeasureSpec.getSize(heightMeasureSpec)
        )
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        var totalHeight = 0
        var titleAnswerIndex = 0
        for (i in 0.until(childCount)) {
            val view = get(i)
            val viewMeasureWidth = view.measuredWidth
            val viewMeasureHeight = view.measuredHeight
            val viewLayoutParams = view.layoutParams as ConstraintLayout.LayoutParams
            val marginStart = viewLayoutParams.marginStart
            val marginEnd = viewLayoutParams.marginEnd
            val topMargin = viewLayoutParams.topMargin
            view.layout(
                marginStart,
                totalHeight + topMargin + movedY,
                viewMeasureWidth + marginEnd,
                totalHeight + viewMeasureHeight + topMargin + movedY
            )

            totalHeight += (viewMeasureHeight + topMargin)
//            if (totalHeight <= mScreenHeight) {
//                usedViewHeight = totalHeight - topMargin - viewMeasureHeight
//            }

            if (i == 0) {
                if (itemHeightMap[titleAnswerIndex] == null) {
                    itemHeightMap[titleAnswerIndex] = 0
                }
                titleAnswerIndex++
            } else {
                if (i + 1 < childCount && titlesCountMap[i + 1]!!) {
                    if (itemHeightMap[titleAnswerIndex] == null) {
                        itemHeightMap[titleAnswerIndex] = totalHeight
                    }
                    titleAnswerIndex++
                }
            }
        }

        //顶部状态栏高度
        val topBarHeight = resources.getStatusBarHeight()
        //底部导航栏高度
        val navigationBarHeight = if (context.checkDeviceHasNavigationBar()) resources.getNavigationBarHeight() else 0
        movedTotalHeight = totalHeight - mScreenHeight + navigationBarHeight + topBarHeight
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        performClick()
        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                downX = event.x.toInt()
                downY = event.y.toInt()
                itemDownY = downY
            }
            MotionEvent.ACTION_MOVE -> {
                val actionMoveX = event.x.toInt()
                val actionMoveY = event.y.toInt()
                val diffValuePerTimes = actionMoveY - itemDownY
                itemMovedX += diffValuePerTimes
                val diffValue = actionMoveY - downY
                if (Math.abs(diffValue) > Math.abs(actionMoveX - downX)) {
                    movedY += diffValue
                    movedY = if (diffValue > 0) {
                        //下滑
                        Math.min(0, movedY)
                    } else {
                        //上滑
                        if (Math.abs(itemMovedX) >= itemHeightMap[indexOfItemMovedX]!! && endIndex < totalChildCount) {
                            addData(endIndex)
                            Log.d(TAG, "itemMovedX:${itemMovedX},height:${itemHeightMap[indexOfItemMovedX]!!}")
                            Log.d(TAG, "endIndex:${endIndex}")
                            indexOfItemMovedX++
                            endIndex++
                        }
                        Math.max(-movedTotalHeight, movedY)
                    }
                }
                requestLayout()
                downX = actionMoveX
                downY = actionMoveY
                itemDownY = actionMoveY
            }
            MotionEvent.ACTION_UP -> {

            }
        }
        return true
    }

    override fun performClick(): Boolean {
        return super.performClick()
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        dataSet = DataSetFactory.createDataSet()
        totalChildCount = dataSet.size
        startIndex = 0
        endIndex = Math.min(showChildCount, totalChildCount)
        setDataSet()
    }

    override fun onViewAdded(view: View?) {
        super.onViewAdded(view)
        //添加完成后再设置边距  这样在MotionEvent.ACTION_MOVE中addView  边距值才会起作用
        view?.layoutParams = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.WRAP_CONTENT,
        ).apply {
            marginStart = context.resources.getDimension(R.dimen.dp_10).toInt()
            marginEnd = context.resources.getDimension(R.dimen.dp_10).toInt()
            topMargin = context.resources.getDimension(R.dimen.dp_10).toInt()
        }
    }

    fun setEditable(canEdited: Boolean) {
        this.canEdited = canEdited
    }

    fun getAnswers():MutableList<String> {
        val answerStr = mutableListOf<String>()
        //先按key排序
        val newItemMap = itemMap.entries.sortedBy { it.key }
            .associateBy({ it.key }, { it.value })
        for ((index, item) in newItemMap) {
            if (item != null) {
                val builder = StringBuilder()
                builder.append(index)
                for (i in 0.until((item.size))) {
                    val itemValue = item[i]
                    if (itemValue == 1) {
                        builder.append(" ").append("${'A' + i}")
                    }
                }
                answerStr.add(builder.toString())
            }
        }
        return answerStr
    }

    private fun setDataSet() {
        for (titleIndex in startIndex.until(endIndex)) {
            addData(titleIndex)
        }
    }

    private fun addData(titleIndex: Int) {
        Log.d(TAG, "addData---titleIndex:${titleIndex}")
        val paperContent = dataSet[titleIndex]
        titleAnswersIndex += 1
        titlesCountMap[titleAnswersIndex] = true
        if (QuestionType.NO_GRAPH.value == paperContent.questionType) {
            //无图
            val titleLayout = if (titleViews[titleIndex] == null) {
                val view = LayoutInflater.from(context)
                    .inflate(R.layout.paper_title_type_no_graph_layout, this, false)
                titleViews[titleIndex] = view
                view
            } else {
                titleViews[titleIndex]!!
            }
            val titleTv = titleLayout.findViewById<AppCompatTextView>(R.id.no_graph_title_tv)
            titleTv.text = paperContent.title

            addView(
                titleLayout,
                ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.MATCH_PARENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT
                )
            )
        } else if (QuestionType.FOUR_GRAPHS.value == paperContent.questionType) {
            //四图
            val titleLayout = if (titleViews[titleIndex] == null) {
                val view = LayoutInflater.from(context)
                    .inflate(R.layout.paper_title_type_four_graphs_layout, this, false)
                titleViews[titleIndex] = view
                view
            } else {
                titleViews[titleIndex]!!
            }

            val titleTv = titleLayout.findViewById<AppCompatTextView>(R.id.four_graphs_title_tv)
            titleTv.text = paperContent.title

            val tvGraphA = titleLayout.findViewById<AppCompatTextView>(R.id.four_graphs_tv_a)
            tvGraphA.text = "图a"

            val tvGraphB = titleLayout.findViewById<AppCompatTextView>(R.id.four_graphs_tv_b)
            tvGraphB.text = "图b"

            val tvGraphC = titleLayout.findViewById<AppCompatTextView>(R.id.four_graphs_tv_c)
            tvGraphC.text = "图c"

            val tvGraphD = titleLayout.findViewById<AppCompatTextView>(R.id.four_graphs_tv_d)
            tvGraphD.text = "图d"

            addView(
                titleLayout,
                ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.MATCH_PARENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT
                )
            )
        }

        var imageViewArr: Array<AppCompatImageView?>? = null
        if (paperContent.singleChoice) {
            imageViewArr = arrayOfNulls(paperContent.answerItems.size)
        }

        for (answerIndex in 0.until(paperContent.answerItems.size)) {

            titleAnswersIndex += 1
            titlesCountMap[titleAnswersIndex] = false

            val answerItem = paperContent.answerItems[answerIndex]

            val answerLayout = if (answerViews["${titleIndex}${answerIndex}"] == null) {
                val view =
                    LayoutInflater.from(context).inflate(R.layout.paper_answers_layout, this, false)
                answerViews["${titleIndex}${answerIndex}"] = view
                view
            } else {
                answerViews["${titleIndex}${answerIndex}"]!!
            }

            val answerTv = answerLayout.findViewById<AppCompatTextView>(R.id.select_item_tv)
            answerTv.text = answerItem

            val answerIv = answerLayout.findViewById<AppCompatImageView>(R.id.select_item_iv)
            if (paperContent.singleChoice) {
                if (imageViewArr != null) {
                    imageViewArr[answerIndex] = answerIv
                }

                if (answerIndex == paperContent.answerItems.size - 1) {
                    imageViewMap[titleIndex + 1] = imageViewArr!!
                }
            }

            answerIv.setOnClickListener {
                val cannotEdited = !canEdited
                if (cannotEdited) {
                    return@setOnClickListener
                }

                val intArray = itemMap[titleIndex + 1]
                if (paperContent.singleChoice) {
                    if (intArray == null) {
                        val newIntArray = IntArray(paperContent.answerItems.size)
                        answerIv.setBackgroundResource(R.drawable.answer_selected_bg)
                        newIntArray[answerIndex] = 1
                        itemMap[titleIndex + 1] = newIntArray
                    } else {
                        for (imageView in imageViewMap[titleIndex + 1]!!) {
                            imageView?.setBackgroundResource(R.drawable.answer_unselected_bg)
                        }

                        for (i in intArray.indices) {
                            if (answerIndex == i) {
                                intArray[i] = 1
                                answerIv.setBackgroundResource(R.drawable.answer_selected_bg)
                            } else {
                                intArray[i] = 0
                            }
                        }

                        itemMap[titleIndex + 1] = intArray
                    }
                } else {
                    if (intArray == null) {
                        val newIntArray = IntArray(paperContent.answerItems.size)
                        answerIv.setBackgroundResource(R.drawable.answer_selected_bg)
                        newIntArray[answerIndex] = 1
                        itemMap[titleIndex + 1] = newIntArray
                    } else {
                        if (intArray[answerIndex] == 1) {
                            answerIv.setBackgroundResource(R.drawable.answer_unselected_bg)
                            intArray[answerIndex] = 0
                            itemMap[titleIndex + 1] = intArray
                        } else {
                            answerIv.setBackgroundResource(R.drawable.answer_selected_bg)
                            intArray[answerIndex] = 1
                            itemMap[titleIndex + 1] = intArray
                        }
                    }
                }
            }

            addView(
                answerLayout,
                ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.MATCH_PARENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT
                )
            )
        }
    }

    fun skipTo(index: Int) {
        movedY = -itemHeightMap[index]!!
        requestLayout()
    }

    companion object {
        const val TAG = "PaperContainer"
    }
}